#define _CRT_SECURE_NO_DEPRECATE
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#pragma comment(lib,"Ws2_32.lib" )
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#define SIZE 1024

void write_file(int sockfd, struct sockaddr_in* client_addr) {
    int n;
    FILE* fp;
    char filename[] = "recv.txt";
    char buffer[SIZE];
    char client_ip[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &(client_addr->sin_addr), client_ip, INET_ADDRSTRLEN);

    fp = fopen(filename, "w");
    if (fp == NULL) {
        perror("[-]Error opening file");
        return;
    }

    while (1) {
        n = recv(sockfd, buffer, SIZE, 0);
        if (n < 0) {
            // 接收数据出错，关闭文件和套接字，删除文件
            printf("IP：%s 发来 %s 文件过程中失去连接。\n", client_ip, filename);
            fclose(fp);
            closesocket(sockfd);
            remove(filename);
            return;
        } else if (n == 0) {
            // 客户端正常关闭连接
            break;
        }
        // 将接收到的数据写入文件
        fprintf(fp, "%.*s", n, buffer);
        ZeroMemory(buffer, SIZE);
    }
    // 正常关闭文件
    fclose(fp);
}

void start()
{
    // 修改为 C 语言的初始化方式
    WORD version = 0;
    WSADATA wsadata;
    int socket_return = 0;
    version = MAKEWORD(2, 0);
    socket_return = WSAStartup(version, &wsadata);
    if (socket_return != 0)
    {
        exit(0);
    }
}

int main()
{
    start();
    char ip[] = "127.0.0.1";
    int port = 8081;
    int e;
    int sockfd, new_sock;
    struct sockaddr_in server_addr, new_addr;
    int addr_size;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    if (sockfd < 0)
    {
        perror("[-]Error in socket");
        exit(1);
    }
    printf("[+]Server socket created successfully.\n");

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);  // 使用htons转换端口
    server_addr.sin_addr.s_addr = inet_addr(ip);

    e = bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
    if (e < 0) {
        perror("[-]Error in bind");
        exit(1);
    }
    printf("[+]Binding successfull.\n");

    if (listen(sockfd, 10) == 0) {
        printf("[+]Listening....\n");
    }
    else {
        perror("[-]Error in listening");
        exit(1);
    }

    addr_size = sizeof(new_addr);
    new_sock = accept(sockfd, (struct sockaddr*)&new_addr, &addr_size);
    if (new_sock < 0) {
        perror("[-]Error in accept");
        exit(1);
    }

    printf("[+]Connection accepted from %s:%d\n",
        inet_ntoa(new_addr.sin_addr), ntohs(new_addr.sin_port));

    write_file(new_sock, &new_addr);
    printf("[+]File transfer completed or handled.\n");
    closesocket(new_sock);
    closesocket(sockfd);
    WSACleanup();

    return 0;
}
